package cc.facesign.admin.service.impl;

import cc.facesign.admin.bean.*;
import cc.facesign.admin.bean.query.ConfQuery;
import cc.facesign.admin.bean.query.UserQuery;
import cc.facesign.admin.bean.vo.AddUserVo;
import cc.facesign.admin.bean.vo.ConfVo;
import cc.facesign.admin.bean.vo.DeptVo;
import cc.facesign.admin.bean.vo.UserVo;
import cc.facesign.admin.mapper.TblUserMapper;
import cc.facesign.admin.service.*;
import cc.facesign.security.bean.LoginUser;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2022-05-06
 */
@Service
@Transactional
public class TblUserServiceImpl extends ServiceImpl<TblUserMapper, TblUser> implements TblUserService {

    @Autowired
    private TblDeptService deptService;

    @Autowired
    private TblConfService confService;

    @Autowired
    private TblConfUserService confUserService;

    @Autowired
    private TblManageDeptService manageDeptService;

    @Autowired
    private AclService aclService;

    @Override
    public String getRootDetpIdByUserId(String userId) {
        TblUser user = getById(userId);
        TblDept dept = deptService.getById(user.getDeptId());
        return dept.getRid();
    }

    @Override
    public TblUser getCurrent() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        cc.facesign.security.bean.TblUser suser = loginUser.getUser();

        TblUser user = new TblUser();
        BeanUtils.copyProperties(suser, user);
        return user;
    }

    @Override

    public UserVo getInfoById(String id) {
        return baseMapper.getInfoById(id);
    }

    @Override
    public List<UserVo> getInfoByIdBatch(List<String> ids) {
        if (ids.size() == 0) return new ArrayList<>();
        return baseMapper.getInfoByIdBatch(ids);
    }


    @Override
    public List<DeptVo> getManageDeptList(String userId) {
        List<String> list = baseMapper.getManageDeptByUserId(userId);
        return deptService.getInfoBatch(list);
    }

    @Override
    public List<UserVo> getInfoListByQuery(UserQuery query) {
        String root = query.getRootDeptId();

        // root 不为空，加上root部门
        if (!StringUtils.isEmpty(root)) {
            List<String> childIds = deptService.getChildListByDeptId(query.getRootDeptId()).stream()
                    .map(x -> x.getId())
                    .collect(Collectors.toList());
            if (query.getDeptIds() == null) query.setDeptIds(new ArrayList<>());
            query.getDeptIds().addAll(childIds);
        }

        // deptIds应包括子部门
//        if (query.getDeptIds() != null) {
//            Set<String> childSet = new HashSet<>();
//            for (String deptId : query.getDeptIds()) {
//                List<String> collect = deptService.getChildListByDeptId(deptId).stream()
//                        .map(x -> x.getId())
//                        .collect(Collectors.toList());
//                childSet.addAll(collect);
//            }
//
//            query.getDeptIds().addAll(childSet);
//        }

        // sql直接用部门
        query.setRootDeptId(null);
        return baseMapper.getInfoListByVo(query);
    }

    @Override
    public Set<String> getChildIdsByDeptId(String deptId) {
        Set<String> deptSet = deptService.getChildIdSetByDeptId(deptId);
        UserQuery query = new UserQuery();
        query.setDeptIds(new ArrayList<>(deptSet));

        return getInfoListByQuery(query).stream()
                .map(UserVo::getId)
                .collect(Collectors.toCollection(HashSet::new));
    }

    @Override
    public int countManageForConf(String userId) {

        QueryWrapper<TblConf> w = new QueryWrapper<>();
        w.eq("creater_id", userId)
                .and(x -> x.ne("status", 2))
                .and(x -> x.ne("status", 4));

        return confService.count(w);
    }

    @Override
    public int countManageForDept(String userId) {
        QueryWrapper<TblManageDept> w = new QueryWrapper<>();
        w.eq("user_id", userId);
        return manageDeptService.count(w);
    }

    @Override
    public List<ConfVo> getCreateConfList(String userId) {
        ConfQuery query = new ConfQuery();
        query.setCreaterId(userId);
        return confService.getListByQuery(query);
    }

    @Override
    public String getRid(String userId) {
        TblUser user = getById(userId);
        String deptId = user.getDeptId();
        TblDept dept = deptService.getById(deptId);
        return dept.getRid();
    }

    @Override
    public List<String> getJoinConfIds(String userId) {
        QueryWrapper<TblConfUser> w = new QueryWrapper<>();
        w.eq("user_id", userId);

        return confUserService.list(w).stream()
                .map(x -> x.getConfId())
                .collect(Collectors.toList());
    }

    @Override
    public List<AddUserVo> createUserBatch(String deptId, List<AddUserVo> data) {
        // 获取cardId
        String rid = deptService.getRid(deptId);
        UserQuery query = new UserQuery();
        query.setRootDeptId(rid);
        Set<String> cardIdSet = getInfoListByQuery(query).stream()
                .map(x -> x.getCardId())
                .collect(Collectors.toSet());

        List<AddUserVo> errs = new ArrayList<>();

        List<TblUser> list = new ArrayList<>();
        for (AddUserVo e : data) {
            // 检测cardId是否合法
            if (cardIdSet.contains(e.getCardId())) {
                errs.add(e);
            }

            TblUser user = new TblUser();
            BeanUtils.copyProperties(e, user);
            user.setDeptId(deptId);
            user.setPassword(aclService.getSecret(user.getPassword()));

            list.add(user);
        }

        if (errs.size() == 0) saveBatch(list);
        return errs;
    }


    @Override
    public HashSet<String> getAllManageDeptIdSet(String userId) {
        // 获取被直接管理的部门id
        List<String> list = baseMapper.getManageDeptByUserId(userId);

        HashSet<String> set = new HashSet<>();
        for (String id : list) {
            set.addAll(deptService.getChildIdSetByDeptId(id));
        }

        return set;
    }

}
